﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

using System.IO.IsolatedStorage;
using System.Text;
using SkyReader.TransferDataService;
using Microsoft.Phone.Shell;
using System.Text.RegularExpressions;
namespace SkyReader
{
    public partial class RootPage : PhoneApplicationPage
    {
        private string bookContent;
        public RootPage()
        {
            InitializeComponent();

            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.Append("1. Download Windows Phone 7 transfer tool from http://wp7transferdatatool.codeplex.com/releases/view/69380#DownloadId=254492");
            sb.AppendLine();
            sb.AppendLine();
            sb.Append("2. Run it on your computer and then click Start Service. (.Net framework 3.5 is required.)");
            sb.AppendLine();
            sb.AppendLine();
            sb.Append("3. Type your computer name above text box and then click the button Connect Server.");

            this.lblInformationHD.Text = sb.ToString();


            // Set default values
            this.lstFontSizeHD.SelectedIndex = 2;
            this.lstFontFamilyHD.SelectedIndex = 7;

            this.lstFontSizeSD.SelectedIndex = 2;
            this.lstFontFamilySD.SelectedIndex = 7;

            PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Disabled;

            Deployment.Current.Dispatcher.BeginInvoke(BindBookList);
        }

        #region books
        private void btnOpenBook_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            string fileName = button.Tag.ToString();
            IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
            settings["VARIABLE_CURRENTFILENAME"] = fileName;

            NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
        }

        private void menuItemOpen_Click(object sender, RoutedEventArgs e)
        {
            FrameworkElement item = sender as FrameworkElement;
            string fileName = item.Tag.ToString();
            IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
            settings["VARIABLE_CURRENTFILENAME"] = fileName;

            NavigationService.Navigate(new Uri("/MainPage.xaml", UriKind.Relative));
        }

        private void menuItemDelete_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show("This Book will be deleted from your bookshelf.", "Delete book?", MessageBoxButton.OKCancel);
            if (result == MessageBoxResult.OK)
            {
                string bookId = ((FrameworkElement)sender).Tag.ToString();
                IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
                Book book = settings[bookId] as Book;

                IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication();
                if (isoFile.FileExists(book.FileName))
                {
                    isoFile.DeleteFile(book.FileName);
                }

                settings.Remove(bookId);
                settings.Save();

                // rebind book list
                BindBookList();
            }
        }

        private List<Book> bookList;
        private void BindBookList()
        {
            bookList = new List<Book>();
            IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;

            foreach (var setting in settings)
            {
                if (setting.Value is Book)
                {
                    Book book = setting.Value as Book;
                    bookList.Add(book);
                }
            }

            // sort book list according to title of the book
            var sortBooks = from sBook in bookList
                            orderby sBook.DateCreated descending
                            select sBook;
            List<Book> sortBookList = sortBooks.ToList<Book>();
            lstBook.ItemsSource = sortBookList;


            this.panelLoadBooks.Visibility = System.Windows.Visibility.Collapsed;
            this.lstBook.Visibility = System.Windows.Visibility.Visible;


            if (bookList.Count == 0)
            {
                this.lblInformationBooks.Visibility = System.Windows.Visibility.Visible;
            }
            else
            {
                this.lblInformationBooks.Visibility = System.Windows.Visibility.Collapsed;
            }
        }
        #endregion



        #region hard disk
        private void lstFontSizeHD_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.lblPreviewHD != null)
            {
                ListPicker listPicker = sender as ListPicker;
                this.lblPreviewHD.FontSize = Convert.ToDouble(listPicker.SelectedItem.ToString());
            }
        }

        private void lstFontFamilyHD_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.lblPreviewHD != null)
            {
                ListPicker listPicker = sender as ListPicker;
                this.lblPreviewHD.FontFamily = new FontFamily(listPicker.SelectedItem.ToString());
            }
        }


        private void btnDownloadFile_Click(object sender, RoutedEventArgs e)
        {
            this.panelLoadHD.Visibility = System.Windows.Visibility.Visible;
            this.contentPanelHD.Visibility = System.Windows.Visibility.Collapsed;
            this.lblLoadingHD.Text = "Downloading...";

            Button button = sender as Button;
            string fileName = button.Tag.ToString();

            string title;
            int lastIndex = fileName.LastIndexOf('.');
            title = fileName.Substring(0, lastIndex);
            this.txtTitleHD.Text = title;
            this.lblPreviewHD.Text = title;



            TransferDataServiceClient client = new TransferDataServiceClient();
            client.TransferFileCompleted += new EventHandler<TransferFileCompletedEventArgs>(client_TransferFileCompleted);
            client.TransferFileAsync(fileName, 0, -1);
        }

        private void client_TransferFileCompleted(object sender, TransferFileCompletedEventArgs e)
        {
            // Get book content
            byte[] buffer = e.Result;
            bookContent = Encoding.UTF8.GetString(buffer, 0, buffer.Length);



            this.lblPreviewHD.FontFamily = new System.Windows.Media.FontFamily(this.lstFontFamilyHD.SelectedItem.ToString());
            this.lblPreviewHD.FontSize = Convert.ToDouble(this.lstFontSizeHD.SelectedItem);

            this.panelLoadHD.Visibility = System.Windows.Visibility.Collapsed;
            this.panelSaveHD.Visibility = System.Windows.Visibility.Visible;

            this.lblLoadingHD.Text = "Loading...";
        }


        private string bookId;
        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            bookId = "BOOK" + this.txtTitleHD.Text.Trim();
            IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
            if (settings.Contains(bookId))
            {
                MessageBoxResult result = MessageBox.Show("There is already a book with the same title in the book shelf, are you sure you want to replace this book?", "Replace book?", MessageBoxButton.OKCancel);
                if (result == MessageBoxResult.Cancel)
                {
                    return;
                }
            }

            // show waiting for 
            panelSaveHD.Visibility = System.Windows.Visibility.Collapsed;
            this.panelLoadHD.Visibility = System.Windows.Visibility.Visible;
            lblLoadingHD.Text = "Saving and creating page index ...";

            Deployment.Current.Dispatcher.BeginInvoke(SaveBook);
        }

        private void SaveBook()
        {
            //progBar.IsIndeterminate = false;

            Book book = null;
            IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
            if (settings.Contains(bookId))
            {
                book = settings[bookId] as Book;
            }
            else
            {
                book = book = new Book()
                {
                    Title = this.txtTitleHD.Text.Trim(),
                    FileName = string.Format("{0}.txt", Guid.NewGuid()),
                    CurrentPage = 1,
                    MarkList = new List<Mark>()
                };
            }

            settings[bookId] = book;
            settings.Save();
            // 2. save book into iso folder 
            IsolatedStorageFile isoFile = IsolatedStorageFile.GetUserStoreForApplication();
            if (isoFile.FileExists(book.FileName))
            {
                isoFile.DeleteFile(book.FileName);
            }

            using (IsolatedStorageFileStream isoFs = isoFile.CreateFile(book.FileName))
            {
                byte[] content = Encoding.UTF8.GetBytes(bookContent);
                isoFs.Write(content, 0, content.Length);
                book.DateCreated = DateTime.Now;
                book.Size = string.Format("{0:N} KB", content.Length / 1024);
            }

            // 3. generate page index of the book
            book.PageDict = new Dictionary<int, int>();
            book.FontSize = Convert.ToDouble(this.lstFontSizeHD.SelectedItem.ToString());
            book.FontFamily = this.lstFontFamilyHD.SelectedItem.ToString();

            string overflowContent = string.Empty;
            int point = 0;
            int pagePoint = 0;
            int currentPage = 0;

            TextBlock textBlock = new TextBlock()
            {
                TextWrapping = TextWrapping.Wrap,
                FontSize = book.FontSize,
                FontFamily = new FontFamily(book.FontFamily),
                Width = SystemConst.PAGE_WIDTH,
                Height = SystemConst.PAGE_HIGHT
            };



            PageBuilder page = new PageBuilder(textBlock);
            while (point != bookContent.Length)
            {
                string line = string.Empty;
                if (overflowContent.Length == 0)
                {
                    if (point + 100 < bookContent.Length)
                    {
                        line = bookContent.Substring(point, 100);
                    }
                    else
                    {
                        line = bookContent.Substring(point);
                    }

                    point = point + 100;
                    if (point > bookContent.Length)
                    {
                        point = bookContent.Length;
                    }
                }
                else
                {
                    line = overflowContent;
                }

                overflowContent = page.Append(line);
                if (overflowContent.Length != 0)
                {
                    currentPage = currentPage + 1;
                    book.PageDict.Add(currentPage, pagePoint);
                    pagePoint = pagePoint + page.Content.Length;
                    page = new PageBuilder(textBlock);
                }
            }
            currentPage = currentPage + 1;
            book.PageDict.Add(currentPage, pagePoint);

            MessageBox.Show("This book has been added to the book shelf.", "Save successful", MessageBoxButton.OK);

            lblLoadingHD.Text = "Loading ...";
            panelLoadHD.Visibility = System.Windows.Visibility.Collapsed;
            panelSaveHD.Visibility = System.Windows.Visibility.Collapsed;
            contentPanelHD.Visibility = System.Windows.Visibility.Visible;
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            contentPanelHD.Visibility = System.Windows.Visibility.Visible;
            panelSaveHD.Visibility = System.Windows.Visibility.Collapsed;
        }
        #endregion

        private void client_GetFielsCompleted(object sender, GetFielsCompletedEventArgs e)
        {
            panelLoadHD.Visibility = System.Windows.Visibility.Collapsed;
            contentPanelHD.Visibility = System.Windows.Visibility.Visible;
            if (e.Error == null)
            {
                List<TFileInfo> fileList = e.Result;
                lstFile.ItemsSource = fileList;
                panelNoService.Visibility = System.Windows.Visibility.Collapsed;
                lstFile.Visibility = System.Windows.Visibility.Visible;

                IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
                settings["computerName"] = this.txtComputerName.Text;
                settings.Save();
            }
            else
            {
                panelNoService.Visibility = System.Windows.Visibility.Visible;
                lstFile.Visibility = System.Windows.Visibility.Collapsed;
                MessageBox.Show("Conneting server is faild", "Error", MessageBoxButton.OK);
            }
        }


        private void btnConnectServer_Click(object sender, RoutedEventArgs e)
        {
            this.GetFilesFromHardDisk();
        }

        private void Pivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            PivotItem selectItem = e.AddedItems[0] as PivotItem;
            if (selectItem.Header.ToString() == "hard disk")
            {
                IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;

                if (settings.Contains("computerName"))
                {
                    this.txtComputerName.Text = settings["computerName"].ToString();
                }
                this.GetFilesFromHardDisk();
            }

            if (selectItem.Header.ToString() == "books")
            {
                Deployment.Current.Dispatcher.BeginInvoke(BindBookList);
            }


            if (selectItem.Header.ToString() == "skydrive")
            {
                //this.webBrowser.Navigating += new EventHandler<NavigatingEventArgs>(webBrowser_Navigating);
                this.webBrowser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(webBrowser_Navigated);
                //this.webBrowser.LoadCompleted += new System.Windows.Navigation.LoadCompletedEventHandler(webBrowser_LoadCompleted);
            }
        }

        private string fileName = string.Empty;
        private string folderUri = string.Empty;
        private void webBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            string a = this.webBrowser.SaveToString();
            /*
            if (e.Uri.AbsoluteUri.Contains("browse.aspx"))
            {
                this.folderUri = e.Uri.AbsoluteUri;
            }

            if (e.Uri.AbsoluteUri.Contains("self.aspx"))
            {
                System.Threading.Thread.Sleep(2000);

                string htmlContent = this.webBrowser.SaveToString();
                int startIndex = htmlContent.IndexOf("<TITLE>") + 7;
                int lastIndex = htmlContent.IndexOf(" - Windows Live</TITLE>", startIndex);
                if (lastIndex != -1)
                {
                    fileName = htmlContent.Substring(startIndex, lastIndex - startIndex);
                }
            }

            LoadPanelSD.Visibility = System.Windows.Visibility.Collapsed;
            ContentPanel.Visibility = System.Windows.Visibility.Visible;


            // Beacuse web control need to take some time load content of text after download book, system show load panel and hide web control
            if (Regex.IsMatch(e.Uri.AbsoluteUri, @"^https://\w{1,50}.\w{1,50}.livefilestore.com/")
              && e.Uri.AbsoluteUri.IndexOf("login.aspx", StringComparison.CurrentCultureIgnoreCase) == -1)
            {
                LoadPanelSD.Visibility = System.Windows.Visibility.Visible;
                ContentPanel.Visibility = System.Windows.Visibility.Collapsed;
            }
            */
        }

        private void webBrowser_Navigating(object sender, NavigatingEventArgs e)
        {
            string s ="1";
            //if (Regex.IsMatch(e.Uri.AbsoluteUri, @"^https://\w{1,50}.\w{1,50}.livefilestore.com/")
            //    && e.Uri.AbsoluteUri.IndexOf("login.aspx", StringComparison.CurrentCultureIgnoreCase) == -1)
            //{
            //    if (this.fileName.EndsWith(".txt", StringComparison.CurrentCultureIgnoreCase) == false)
            //    {
            //        MessageBox.Show("The file format is not supported. The book must be a plain text or HTML file.", "Incorrect file format", MessageBoxButton.OK);
            //        e.Cancel = true;
            //        return;
            //    }
            //    lblLoading.Text = "Downloading...";
            //}
            //else
            //{
            //    lblLoading.Text = "Loading...";
            //}

            //LoadPanelSD.Visibility = System.Windows.Visibility.Visible;
            //ContentPanel.Visibility = System.Windows.Visibility.Collapsed;
        }

        private void webBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            // show save panel
            /*
            if (Regex.IsMatch(e.Uri.AbsoluteUri, @"^https://\w{1,50}.\w{1,50}.livefilestore.com/")
               && e.Uri.AbsoluteUri.IndexOf("login.aspx", StringComparison.CurrentCultureIgnoreCase) == -1)
            {
                // Get book title
                string title;
                int lastIndex = fileName.LastIndexOf('.');
                title = fileName.Substring(0, lastIndex);
                this.txtTitleSD.Text = title;

                // Get book content
                bookContent = this.webBrowser.SaveToString();
                int startIndex = 32;
                lastIndex = bookContent.LastIndexOf("</PRE></BODY></HTML>");
                bookContent = bookContent.Substring(startIndex, lastIndex - startIndex);
                this.lblPreviewSD.Text = string.Format("{0} ...", bookContent.Substring(0, 35));

                this.lblPreviewSD.FontFamily = new System.Windows.Media.FontFamily(this.lstFontFamilySD.SelectedItem.ToString());
                this.lblPreviewSD.FontSize = Convert.ToDouble(this.lstFontSizeSD.SelectedItem);

                LoadPanelSD.Visibility = System.Windows.Visibility.Collapsed;
                SavePanelSD.Visibility = System.Windows.Visibility.Visible;
            }
             */
        }

        private void GetFilesFromHardDisk()
        {
            string computerName = this.txtComputerName.Text.Trim();
            if (string.IsNullOrEmpty(computerName))
            {
                computerName = "localhost";
            }

            panelLoadHD.Visibility = System.Windows.Visibility.Visible;
            contentPanelHD.Visibility = System.Windows.Visibility.Collapsed;
            panelSaveHD.Visibility = System.Windows.Visibility.Collapsed;
            TransferDataServiceClient client = null;
            client = new TransferDataServiceClient();
            client.Endpoint.Address = new System.ServiceModel.EndpointAddress(string.Format("http://{0}:18000/TransferDataService/", computerName));

            client.GetFielsCompleted += new EventHandler<GetFielsCompletedEventArgs>(client_GetFielsCompleted);
            client.GetFielsAsync("*.txt");
        }

        private void lstFontFamilySD_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.lblPreviewSD != null)
            {
                ListPicker listPicker = sender as ListPicker;
                this.lblPreviewSD.FontFamily = new FontFamily(listPicker.SelectedItem.ToString());
            }
        }

        private void lstFontSizeSD_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.lblPreviewSD != null)
            {
                ListPicker listPicker = sender as ListPicker;
                this.lblPreviewSD.FontSize = Convert.ToDouble(listPicker.SelectedItem.ToString());
            }
        }

    }
}